package com.shutuo.callnumqixintian;

import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.instwall.callbase.data.CallNumData;
import com.instwall.callnumlistener.CallNumNotification;
import com.instwall.net.NetCoreException;
import com.shutuo.callnumqixintian.screeninfo.QXTianInfo;
import com.shutuo.callnumqixintian.screeninfo.ScreenManager;
import com.shutuo.callnumqixintian.utils.ApiUrl;
import com.shutuo.callnumqixintian.utils.QiXinTianJsParamsUtil;
import com.shutuo.callnumqixintian.utils.ShardPreferencesUtil;

import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;

import ashy.earl.common.app.App;
import ashy.earl.common.util.L;
import ashy.earl.common.util.NetworkChangeHelper;


public class QixintianManager {

    public static final String TAG = "QiXinTianCallNumber  ";

    static final String STAG = "[Manager]  ";

    private String SN = "";
    private Socket loginSocket;
    private Socket registerSocket;
    private Handler handler ;
    private static QixintianManager qixintianManager = null;


    private QixintianManager(){
        registerSocket = new Socket();
        loginSocket = new Socket();
        HandlerThread handlerThread = new HandlerThread("Qixintian");
        handlerThread.start();
        ScreenManager.get().init();
        ScreenManager.ScreenListener screenListener = new ScreenManager.ScreenListener() {
            @Override
            public void onScreenInfoChanged(QXTianInfo info) {
                init();
            }
        };
        ScreenManager.get().setScreenListener(screenListener);
        handler = new Handler(handlerThread.getLooper());

        NetworkChangeHelper mNetwork = NetworkChangeHelper.get();

        NetworkChangeHelper.NetworkListener mNetworkListener = new NetworkChangeHelper.NetworkListener() {
            @Override
            public void onNetworkChanged(boolean hasActiveNetwork, String type, String name) {
                if (hasActiveNetwork) {
                    init();
                }
            }
        };
        mNetwork.addNetworkListener(mNetworkListener);
        CallNumNotification.getCallNumNotification().addPlayerStateListener(playerStateListener);
    }

    private CallNumNotification.PlayerStateListener playerStateListener = new CallNumNotification.PlayerStateListener(){

        @Override
        public void onPlayerStateChanged() {
            long shop_id = ShardPreferencesUtil.getShopId(App.getAppContext(),0);
            if(shop_id!=0){
                LoginTask loginTask = new LoginTask();
                handler.post(loginTask);
            }
        }
    };

    public static QixintianManager getInstance(){
        if (qixintianManager!=null) return null;
        synchronized (QixintianManager.class){
            qixintianManager = new QixintianManager();
        }
        return qixintianManager;
    }


    private void init(){
        Log.d(TAG, STAG + "init");
        QXTianInfo qxTianInfo = getQXTianInfo();
        if (qxTianInfo == null) return;

        if (!TextUtils.isEmpty(qxTianInfo.qxtSn)){
            long shop_id = ShardPreferencesUtil.getShopId(App.getAppContext(),0);
            boolean isSNChanged = !qxTianInfo.qxtSn.equals(ShardPreferencesUtil.getSNCode(App.getAppContext(), null));
            if (shop_id!=0 && !isSNChanged){
                LoginTask loginTask = new LoginTask();
                handler.post(loginTask);
                loginSocket.setup("wss://orderqueuebridge.acewill.net/api/register?sid="+shop_id+"&termId="+qxTianInfo.qxtSn,loginListener);
            }else {
                initRegister();
            }
        }else {
            stopRegister();
        }
    }



    private void initRegister(){
        Log.d(TAG, STAG + "initRegister");
        QXTianInfo qxTianInfo = getQXTianInfo();
        if (qxTianInfo == null) return;
        Log.d(TAG,STAG+qxTianInfo.toString());
            if(!TextUtils.isEmpty(qxTianInfo.qxtSn)){
                SN = qxTianInfo.qxtSn;
                Log.d(TAG, STAG + "initRegister -> sid is : "+qxTianInfo.qxtToken +" , sn_code : "+qxTianInfo.qxtSn);
                registerSocket.setup("wss://orderqueuebridge.acewill.net/api/register?sid="+qxTianInfo.qxtToken+"&termId="+qxTianInfo.qxtSn,
                        registerListener);
            }
    }



    private QXTianInfo getQXTianInfo(){
        QXTianInfo qxTianInfo;
        qxTianInfo = ScreenManager.get().getQxTianInfo();
        return qxTianInfo;
    }

    private void stopRegister(){
        if (registerSocket!=null){
            registerSocket.teardown();
        }
        if (loginSocket!=null){
            loginSocket.teardown();
        }
        CallNumNotification.getCallNumNotification().removePlayerStateListener(playerStateListener);

    }

    private Socket.WSListener registerListener = new Socket.WSListener() {
        @Override
        public void onStateChanged(int state, String detail) {
            Log.d(TAG, "register state changed : "+registerSocket.stateToString(state) +
                    " -> "+registerSocket.stateToString(state)+" detail : "+detail);
        }

        @Override
        public void onCmd(String msg) {

            Log.d(TAG,STAG+"registerListener msg : " + msg);
            RegisterTask registerTask = new RegisterTask(msg,SN);
            handler.post(registerTask);
        }
    };

    public String trimFirstAndLastChar(String str, String element) {
        boolean beginIndexFlag = true;
        boolean endIndexFlag = true;
        if(str==null) return null;
        do{
            L.d(TAG,STAG+str);
            int beginIndex = str.indexOf(element) == 0 ? 1 : 0;
            int endIndex = str.lastIndexOf(element) + 1 == str.length() ? str.lastIndexOf(element) : str.length();
            str = str.substring(beginIndex, endIndex);
            beginIndexFlag = (str.indexOf(element) == 0);
            endIndexFlag = (str.lastIndexOf(element) + 1 == str.length());
        } while (beginIndexFlag || endIndexFlag);
        return str;
    }

    private Socket.WSListener loginListener = new Socket.WSListener() {
        @Override
        public void onStateChanged(int state, String detail) {
            Log.d(TAG, "login state changed : "+loginSocket.stateToString(state) +
                    " -> "+loginSocket.stateToString(state)+" detail : "+detail);
        }

        @Override
        public void onCmd(String msg) {
            Log.d(TAG,STAG+"loginListener msg : "+msg);
            LoginTask loginTask = new LoginTask();
            handler.post(loginTask);
        }
    };



    class  RegisterTask implements Runnable {

        private String message;
        private String termId;
        RegisterTask(String msg, String termId){
            this.message = msg;
            this.termId = termId;
        }

        @Override
        public void run() {
            Log.d(TAG, STAG+"RegisterTask run: ");
            try {
                JSONObject msgObject = new JSONObject(message);
                String body = msgObject.optString("body");
//                body = trimFirstAndLastChar(body,"\"");
                Log.d(TAG,STAG+"body : "+body);
                JSONObject jsonObject = new JSONObject(body);
                String appKey = jsonObject.optString("appkey");
                String appId = jsonObject.optString("appid");
                long shop_id =  Long.parseLong(jsonObject.optString("shop_id"));
                long cashier_id = Long.parseLong(jsonObject.optString("cashier_id"));
                ShardPreferencesUtil.saveAppId(App.getAppContext(),appId);
                ShardPreferencesUtil.saveAppkey(App.getAppContext(),appKey);
                ShardPreferencesUtil.saveShopId(App.getAppContext(),shop_id);
                ShardPreferencesUtil.saveCashierId(App.getAppContext(),cashier_id);
                ShardPreferencesUtil.saveSNCode(App.getAppContext(),termId);
                if (shop_id!= 0){
//                V101172400500
                    Log.d(TAG, STAG+"RegisterTask -> login setup");
                    loginSocket.setup("wss://orderqueuebridge.acewill.net/api/register?sid="+shop_id+"&termId="+termId,loginListener);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    class LoginTask implements Runnable{
        @Override
        public void run() {
            Log.d(TAG, STAG+"LoginTask run: ");
            String appId = ShardPreferencesUtil.getAppId(App.getAppContext(),null);
            String appKey = ShardPreferencesUtil.getAppkey(App.getAppContext(),null);
            long shop_id = ShardPreferencesUtil.getShopId(App.getAppContext(),0);
            long cashier_id = ShardPreferencesUtil.getCashierId(App.getAppContext(),0);
            Log.d(TAG, STAG+"loginTask -> appId="+appId+" ,appKey="+appKey+" ,shop_id="+shop_id+" ,cashier_id="+cashier_id);

            PostBean postBean = ApiUrl.getPostUrl(shop_id,cashier_id,appId,appKey);
            Message message = Message.obtain();
            message.what = 1;
            message.obj =  postBean;
            mHandler.sendMessage(message);
        }
    }


    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {

        //handleMessage为处理消息的方法
        public void handleMessage(@NotNull Message msg){
            super.handleMessage(msg);
            if (msg.what == 1) {
                PostBean postBean = (PostBean) msg.obj;
                onRequest(postBean);
            }
        }
    };


    private void onRequest(PostBean postBean){
        final RequestApi requestApi = new RequestApi(postBean);
            requestApi.makeRequest(new ashy.earl.net.Callback<String, NetCoreException>() {
                @Override
                public void onResult(String result, NetCoreException e) {
                    if(e!=null){
                        Log.d(TAG, STAG+"LoginTask-> request Error : "+e);
                    }
                    if(!TextUtils.isEmpty(result)){
                        String message =  QiXinTianJsParamsUtil.constructQiXinTianJsParams(result);
                        CallNumData callNumData = new CallNumData("qixintian",message);
//                        CallNumNotification.getCallNumNotification().notificationClient(message);
                    }else {
                        Log.d(TAG, STAG+" LoginTask-> request is null");
                    }
                }
            });
    }


}
